package com.sst.common.utils;

import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public  class ThreadPoolUtil {
    // 私有化构造方法，禁止使用new创建对象，保证该对象只有一个
    private ThreadPoolUtil(){
        Boolean flag = false;
        // 防止通过反射对单列的破坏
        synchronized (ThreadPoolUtil.class){
            if(flag == false){
                flag = true;
            }else{
                throw new RuntimeException("单列模式不能通过反射创建对象");
            }
        }
    };

    // 运行时获取服务的cpu的核心数
    static int max = Runtime.getRuntime().availableProcessors();

    private volatile static ThreadPoolExecutor tpe;

    // 对外提供公共方法，返回新建的对象,先判断该对象是否存在，存在直接返回，不存在则新建
    public static ThreadPoolExecutor getThreadPoolExecutor(){
        // 该对象不存在
        if(null == tpe){
            synchronized (ThreadPoolUtil.class){
                if(null == tpe){
                    tpe = new ThreadPoolExecutor(
                            2,
                            max,
                            3,
                            TimeUnit.SECONDS,
                            new LinkedBlockingDeque<>(3),
                            Executors.defaultThreadFactory()
                    );
                    /**
                     * 对象的创建有三步：
                     1：开辟内存空间
                     2：执行构造方法，初始化对象
                     3：将对象指向内存空间

                     在多线程的情况下，可能线程A开辟内存空间后，直接就将对象指向内存空间
                     线程B在线程A还没有执行构造方法的时候就已经开始执行，最终导致B的问题出现，因此要加关键字volatile
                     */
                }
            }
        }
        return tpe;
    }
}
